package xyz.gzdxc.common.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import xyz.gzdxc.common.constant.AuthConstant;
import xyz.gzdxc.common.constant.ResultCode;
import xyz.gzdxc.common.exception.AccountLockException;
import xyz.gzdxc.common.exception.CaptchaException;
import xyz.gzdxc.common.exception.CaptchaTimeoutException;
import xyz.gzdxc.common.exception.UserLoginException;
import xyz.gzdxc.common.service.LoginService;
import xyz.gzdxc.common.service.SessionService;
import xyz.gzdxc.common.util.CookieUtil;
import xyz.gzdxc.common.util.ResultBuilder;
import xyz.gzdxc.common.vo.request.LoginReqVo;
import xyz.gzdxc.common.vo.response.CaptchaResp;
import xyz.gzdxc.common.vo.response.CheckSessionResp;
import xyz.gzdxc.common.vo.response.ResultVo;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.rmi.ServerException;

@RestController
@RequestMapping("/login")
public class LoginController {

    private static final Logger LOG = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    LoginService loginService;

    @Autowired
    SessionService sessionService;

    @RequestMapping("/logintest")
    public String logintest(){

        return "login success...........";
    }

    @GetMapping("/getCheckCode")
    ResultVo<CaptchaResp> getCheckCode(HttpServletRequest request, HttpServletResponse response){
        LOG.info("begin get check code");
        CaptchaResp captchaResp = null;
        try{
            captchaResp = loginService.getCheckCode();
        } catch (Exception e){
            LOG.error("err when generate the check code => {}", e.toString());
            return ResultBuilder.build(ResultCode.SERVER_EXCEPTION);
        }
        LOG.info("end get check code");
        return ResultBuilder.build(ResultCode.SUCCESS, captchaResp);
    }

    @PostMapping("/login")
    ResultVo login(@RequestBody LoginReqVo loginReqVo, HttpServletResponse response) throws Exception{
        String userSessionId = null;
        try{
            userSessionId = loginService.login(loginReqVo);
        } catch (ServerException serverException){
            return ResultBuilder.build(ResultCode.SERVER_EXCEPTION);
        } catch (CaptchaException captchaException){
            return ResultBuilder.build(ResultCode.CAPTCHA_EXCEPTION);
        } catch (CaptchaTimeoutException captchaTimeoutException){
            return ResultBuilder.build(ResultCode.CAPTCHA_TIME_OUT_EXCEPTION);
        } catch (UserLoginException userLoginException){
            return ResultBuilder.build(ResultCode.PWD_USER_EXCEPTION);
        } catch (AccountLockException accountLockException){
            return ResultBuilder.build(ResultCode.ACCOUNT_EXCEPTION);
        }
        //set the cookie to browser, and only the server can modify the cookie
        CookieUtil.setCookie(response, AuthConstant.SESSION_KEY, userSessionId, true);
        return ResultBuilder.build(ResultCode.SUCCESS);
    }

    /**
     * verify the session
     * @param request
     * @param response
     * @return checkSessionResp
     */
    @GetMapping("/checkSession")
    public ResultVo<CheckSessionResp> checkSession(HttpServletRequest request, HttpServletResponse response){
        String loginSession = CookieUtil.getCookieValue(request, AuthConstant.SESSION_KEY);
        CheckSessionResp checkSessionResp = null;
        try{
            checkSessionResp = sessionService.checkSession(loginSession);
        } catch (Exception e){
            e.printStackTrace();
            LOG.info(e.toString());
            return ResultBuilder.build(ResultCode.SERVER_EXCEPTION);
        }
        if(checkSessionResp.isSessionTimeOutFlag() || checkSessionResp.isTimeOutFlag()){
            CookieUtil.removeCookie(request, response, AuthConstant.SESSION_KEY);
        }
        return ResultBuilder.build(ResultCode.SUCCESS, checkSessionResp);
    }

    @GetMapping("/logout")
    ResultVo logout(HttpServletRequest request, HttpServletResponse response){
        String loginSession = CookieUtil.getCookieValue(request, AuthConstant.SESSION_KEY);
        LOG.info("the session logout => {}", loginSession);
        try {
            loginService.logout(loginSession);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultBuilder.build(ResultCode.SERVER_EXCEPTION);
        }
        CookieUtil.removeCookie(request, response, AuthConstant.SESSION_KEY);
        return ResultBuilder.build(ResultCode.SUCCESS);
    }
}
